package com.bluefeather.songlyric;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.GridLayout;
import android.widget.GridLayout.Spec;
import android.widget.ImageView;
import android.widget.TextView;

public class MusicActivity extends Activity {
	
	static private String		TAG = "Music";
	
	static private int[]		BACKGROUNDS = new int[] {
		R.drawable.music_bg1, R.drawable.music_bg2, R.drawable.music_bg3, R.drawable.music_bg4,
		R.drawable.music_bg5, R.drawable.music_bg6, R.drawable.music_bg7, R.drawable.music_bg8
	};
	
	private String				_where;
	private TextView			_title;
	private TextView			_author;
	private GridLayout			_grid = null;
	private Cursor				_lyricCursor = null;
	private int					_background = 0;
	
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Bundle extras = getIntent().getExtras();
		_where = extras.getString("LYRIC_WHERE");
		setContentView(R.layout.activity_music);
		View view = findViewById(R.id.music_layout);
		SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(SongLyricApp.instance());
		if(sp.getBoolean("BG_PICTURE", true)) {
			_background = (int)(Math.random() * BACKGROUNDS.length);
			view.setBackgroundResource(BACKGROUNDS[_background]);
		}
		View scrollView = findViewById(R.id.scrollView1);
		scrollView.setOnTouchListener(new LyricSwitcher());
		_grid = (GridLayout) view.findViewById(R.id.music_grid);
		_title = (TextView) view.findViewById(R.id.lyric_title);
		_author = (TextView) view.findViewById(R.id.lyric_author);
		_lyricCursor = DB.instance().getLyricList(_where);
		if(_lyricCursor.getCount() > 0)
			display();
		else
			SongLyricApp.instance().showToast("Not found");
	}
	
	private String				_musicName;
	private int 				_musicLines1;
	private int 				_musicLines2;
	
	private void display() {
		int musicId = _lyricCursor.getInt(_lyricCursor.getColumnIndex(DB.LYRIC._MUSIC));
		Cursor c2 = DB.instance().getMusicLines(musicId);
		int maxColumns = 0;
		ArrayList<String> words = new ArrayList<String>();
		while(!c2.isAfterLast()) {
			String s = c2.getString(c2.getColumnIndex(DB.MUSICLINE._WORDS));
			words.add(s);
			if(s.length() > maxColumns)
				maxColumns = s.length();
			c2.moveToNext();
		}
		maxColumns += 3; // to support small differences in lyrics
		c2.close();
		// get music info later than music lines because import is done in musicLines
		Cursor c1 = DB.instance().getMusic(musicId);
		_musicName = c1.getString(c1.getColumnIndex(DB.MUSIC._NAME));
		_musicLines1 = c1.getInt(c1.getColumnIndex(DB.MUSIC._LINES1));
		_musicLines2 = c1.getInt(c1.getColumnIndex(DB.MUSIC._LINES2));
		c1.close();
		int lines = _musicLines1 * 2;
		if(_musicLines2 > 0)
			lines += _musicLines2 * 2 + 1;
		_grid.removeAllViews();
		_grid.setColumnCount(maxColumns);
		_grid.setRowCount(lines + 2);
		int lyricLines = populateLyric();
		populateMusic(lyricLines, words);
		setTitle(_musicName);
	}
	
	public void switchBackground() {
		if(++_background >= BACKGROUNDS.length)
			_background = -1;
		View view = findViewById(R.id.music_layout);
		if(_background >= 0)
			view.setBackgroundResource(BACKGROUNDS[_background]);
		else
			view.setBackground(null);
	}
	
	public void populateNextLyric() {
		if(_lyricCursor.getCount() == 0)
			return;
		_lyricCursor.moveToNext();
		if(_lyricCursor.isAfterLast())
			_lyricCursor.moveToFirst();
		display();
	}
	
	private void populatePrevLyric() {
		if(_lyricCursor.getCount() == 0)
			return;
		_lyricCursor.moveToPrevious();
		if(_lyricCursor.isBeforeFirst())
			_lyricCursor.moveToLast();
		display();
	}
	
	private void populateMusic(int lyricLines, ArrayList<String> words) {
		for(int line = 0; line < _musicLines1 + _musicLines2 && line < lyricLines; ++line) {
			String word = words.get(line);
			int row = line * 2;
			if(line == _musicLines1) { // add a line between the 2 blocks
				Spec rowSpec = GridLayout.spec(row, 1);
				Spec colSpec = GridLayout.spec(0, 1);
				GridLayout.LayoutParams params = new GridLayout.LayoutParams(rowSpec, colSpec);
				params.setGravity(Gravity.CENTER | Gravity.FILL);
				ImageView child = new ImageView(this);
				child.setBackgroundColor(0x000000);
				child.setImageResource(R.drawable.blank);
				_grid.addView(child, params);
			}
			if(line >= _musicLines1)
				row++;
			Spec rowSpec = GridLayout.spec(row, 1);
			for(int col = 0; col < word.length(); ++col) {
				Spec colSpec = GridLayout.spec(col, 1);
				GridLayout.LayoutParams params = new GridLayout.LayoutParams(rowSpec, colSpec);
				params.setGravity(Gravity.CENTER | Gravity.FILL);
				ImageView child = new ImageView(this);
				child.setImageResource(getImageResource(word.charAt(col)));
				child.setBackgroundColor(0x000000);
				_grid.addView(child, params);
			}
		}
	}
	
	private int populateLyric() {
		if(_lyricCursor.getCount() == 0)
			return _musicLines1 + _musicLines2;
		SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(SongLyricApp.instance());
		String fontSizePref = sp.getString("FONT_SIZE", "MEDIATE");
		int fontSize = fontSizePref.equals("LARGE") ? android.R.style.TextAppearance_DeviceDefault_Medium :
			fontSizePref.equals("SMALL") ? android.R.style.TextAppearance_DeviceDefault_Medium :
			android.R.style.TextAppearance_DeviceDefault_Medium;
		int lyricId = _lyricCursor.getInt(_lyricCursor.getColumnIndex(DB.LYRIC._ID));
		StringBuilder title = new StringBuilder();
		title.append(_musicName);
		if(!_lyricCursor.getString(_lyricCursor.getColumnIndex(DB.LYRIC._TITLE)).isEmpty()) {
			title.append(getString(R.string.chinese_dot));
			title.append(_lyricCursor.getString(_lyricCursor.getColumnIndex(DB.LYRIC._TITLE)));
		}
		_title.setText(title);
		_author.setText(_lyricCursor.getString(_lyricCursor.getColumnIndex(DB.LYRIC._DYNASTY)) +
			getString(R.string.chinese_dot) + 
			_lyricCursor.getString(_lyricCursor.getColumnIndex(DB.LYRIC._AUTHOR)));
		Cursor c = DB.instance().getLyricLines(lyricId);
		int lines = c.getCount();
		for(int line = 0; line < lines; ++line) {
			String words = c.getString(c.getColumnIndex(DB.LYRICLINE._WORDS));
			LogDog.i(TAG, "populateLyric line " + line + ":" + words);
			int row = line * 2 + 1;
			if(line >= _musicLines1)
				row ++;
			Spec rowSpec = GridLayout.spec(row, 1);
			for(int col = 0; col < words.length(); ++col) {
				Spec colSpec = GridLayout.spec(col, 1);
				GridLayout.LayoutParams params = new GridLayout.LayoutParams(rowSpec, colSpec);
				params.setGravity(Gravity.CENTER | Gravity.FILL);
				TextView child = new TextView(this);
				child.setTextAppearance(this, fontSize);
				child.setBackgroundColor(0x000000);
				child.setText(words.substring(col, col + 1));
				_grid.addView(child, params);
			}
			c.moveToNext();
		}
		c.close();
		return lines;
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.music, menu);
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int id = item.getItemId();
		if (id == R.id.action_about) {
			Intent i = new Intent(this, DocActivity.class);
			i.putExtra("DOC", "about");
			startActivity(i);
			return true;
		} else if(id == R.id.action_settings) {
			Intent i = new Intent(this, SettingsActivity.class);
			startActivity(i);
			return true;
		} else if(id == R.id.action_bookmark) {
			BookmarkDialog dlg = new BookmarkDialog(this);
			dlg.show();
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
	
	public void bookmarkMusic() {
		int musicId = _lyricCursor.getInt(_lyricCursor.getColumnIndex(DB.LYRIC._MUSIC));
		DB.instance().bookmarkMusic(musicId);
		SongLyricApp.instance().showToast(R.string.bookmarked);
	}
	
	public void deleteLyric() {
		if(_lyricCursor.getCount() == 1) {
			SongLyricApp.instance().showToast(R.string.warning_only_lyric);
			return;
		}
		_grid.removeAllViews();
		int lyricId = _lyricCursor.getInt(_lyricCursor.getColumnIndex(DB.LYRIC._ID));
		DB.instance().deleteLyric(lyricId);
		SongLyricApp.instance().showToast(R.string.deleted);
		_lyricCursor = DB.instance().getLyricList(_where);
		display();
	}
	
	// 平仄中云芸韵运
	static String TONES_STRING = SongLyricApp.instance().getResources().getString(R.string.tones);
	static int[] TONES_ID = new int[] {
		R.drawable.p,
		R.drawable.z,
		R.drawable.zh,
		R.drawable.h,
		R.drawable.w,
		R.drawable.y,
		R.drawable.j
	};
	static private int getImageResource(char ch) {
		for(int i = 0; i < TONES_STRING.length(); ++i)
			if(ch == TONES_STRING.charAt(i))
				return TONES_ID[i];
		return 0;
	}
	
	class LyricSwitcher implements OnTouchListener {

		private static final float	LYRIC_LIMIT = 200f;
		private static final float	BG_LIMIT = 50;
		
		private float			_downX = 0;
		private float			_downY = 0;
		private float			_minX = 0;
		private float			_maxX = 0;
		
		@Override
		public boolean onTouch(View v, MotionEvent event) {
			switch(event.getActionMasked()) {
			case MotionEvent.ACTION_DOWN :
				_downX = event.getX();
				_downY = event.getY();
				_minX = _downX;
				_maxX = _downX;
				break;
			case MotionEvent.ACTION_MOVE :
				float x = event.getX();
				if(x > _maxX)
					_maxX = x;
				else if(x < _minX)
					_minX = x;
				break;
			case MotionEvent.ACTION_UP :
				float dx = event.getX() - _downX;
				float dy = event.getY() - _downY;
				if(Math.abs(dx) > LYRIC_LIMIT && Math.abs(dx) > Math.abs(dy)) {
					if(dx > 0)
						MusicActivity.this.populatePrevLyric();
					else
						MusicActivity.this.populateNextLyric();
					return true;
				} else if(Math.abs(dx) < BG_LIMIT && _maxX - _minX > LYRIC_LIMIT) {
					MusicActivity.this.switchBackground();
				}
				break;
			}
			return false;
		}
		
	}
}
